import { reactive } from "vue";
import { v4 as uuidv4 } from "uuid";
import { tools } from "@/components/low-code/page-designer/utils/index";
import {
  LowCodeImp,
  LowCodeType,
  ComponentImp,
  ComponentImpWithoutMethods,
  CellImp,
  TabImp,
  ModelImp,
  EventCenterImp,
  EventType,
  DataSourceType,
  DataSourceImp,
  GlobalConfig,
  SelectorImp,
} from "./type";
import { Component } from "./component";
import { EventCenter } from "./eventCenter";
import { Model } from "./model";
import { DataSource } from "./dataSource";
import { tableSet } from "@/components/low-code/data/index";
import clone from "clone";

class LowCode implements LowCodeImp {
  static custom: any; //自定义组件挂载点
  isDesigner?: boolean;
  metaRefresh?: string;
  disabled?: boolean;
  currentKey!: string;
  root?: ComponentImp;
  model!: any;
  fieldPool?: any[];
  dataCenter!: { [key: string]: ComponentImp | CellImp | TabImp };
  eventCollection!: Array<EventType>;
  dataSource!: Array<DataSourceType>;
  globalConfig!: GlobalConfig;
  modelController!: ModelImp; //modelController 数据模型对象
  eventCenterController!: EventCenterImp; //eventCenterController 事件控制对象
  dataSourceController!: DataSourceImp; //DataSourceImp 数据源对象
  constructor({
    isDesigner = false,
    root,
    model = {},
    fieldPool,
    eventCollection,
    dataSource,
    globalConfig,
  }: LowCodeType) {

    this.isDesigner = isDesigner;
    console.log("model", model);
    this.disabled = false;
    this.fieldPool = fieldPool;
    this.model = model;
    this.root = root
    this.eventCollection = eventCollection || [
      {
        code: "9303de27-6af7-484e-a695-98b179a6bc35",
        type: "custom",
        options: {},
        describe: "测试事件",
        func: ` const { data , $ , axios , ElMessage } = controller;`,
      },
    ];
    this.dataSource = dataSource || [
      {
        key: uuidv4(),
        name: "测试数据源",
        url: "",
        method: "GET",
        auto: false,
      },
    ];
    this.globalConfig = globalConfig || {
      labelWidth: 100,
      labelPosition: "left",
      size: "default",
    };

    this.init();
  }
  [x: string]: any;
  updateMetaRefresh() {
    this.metaRefresh = uuidv4();
  }
  init() {
    this.initFieldPool();
    this.registrationControl();
    this.buildDomTree();
  }
  initFieldPool() {
    // 序列化字段池
    let fieldMap = {} as any;
    this.fieldPool?.forEach((item) => {
      fieldMap[item.fieldCnName] = "";
    });
    this.model = Object.assign(this.model, fieldMap, {});
  }
  registrationControl() {
    this.modelController = new Model(this); //数据模型初始化
    this.eventCenterController = new EventCenter(this); //事件中心初始化
    this.dataSourceController = new DataSource(this); //数据源初始化
  }
  buildDomTree() {

    this.root = new Component(
      this.root?
      this.root
      :{
        key: "",
        component: "root",
        name: "根容器",
        field: "",
        selector: "",
        group: "page",
        describe: "",
        nestedChain: "",
        componentProps: {
          gridTemplateColumns: 3,
          ref: null,
          labelWidth: 100,
          labelPosition: "left",
          size: "default",
        },
        items: [],
      },
      this
    );
    this.dataCenter = {
      [this.root.key]: this.root,
    };

    if (this.root && this.root.items && this.root.items.length > 0) {
      this.root.items = this.root.items.map((com) => {
        return <Component> this.root?.copyItem(com,true);
      });
    }
    this.updateMetaRefresh();
  }

  setcurrentKey(key: string) {
    this.currentKey = key;
  }
}

const createLowCode = (args: {
  isDesigner?: boolean;
  root?: ComponentImp | undefined;
  model?: any;
  fieldPool?: any[] | undefined;
  eventCollection?: EventType[] | undefined;
  dataSource?: DataSourceType[] | undefined;
  globalConfig?: GlobalConfig | undefined;
}): LowCode => {
  return reactive(
    new LowCode({ ...args, fieldPool: clone(tableSet.value[0].items) })
  );
};

// let lowCode = createLowCode({isDesigner:true});

clone(tableSet.value[0].items);


export { LowCode,  createLowCode };
export type { ComponentImp };
export type { ComponentImpWithoutMethods };
export type { Component };
export type { CellImp };
export type { TabImp };
export type { LowCodeImp };
export type { SelectorImp };
